package com.wootion.dizhi.runData;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.serial.SerialPortWrapper;

import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;


/**
 * Modbus工具类
 */
public class ModbusUtil {
    /**
     * 读取保持寄存器的值
     * @param master ModbusMaster对象
     * @param slaveId 从站ID
     * @param startOffset 起始地址
     * @param numberOfRegisters 读取寄存器的数量
     * @return 读取到的数据
     */
    public static short[] readHoldingRegisters(ModbusMaster master, int slaveId, int startOffset, int numberOfRegisters) throws ModbusTransportException, InterruptedException {
        ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, startOffset, numberOfRegisters);
        try {
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);
            if (response.isException()) {
                System.out.println("读取时发生异常");
                return null;
            } else {
                return response.getShortData();
            }
        } catch (ModbusTransportException e) {
            System.out.println("从机地址为"+slaveId+"的设备没有读取到值");
            return null;
        }
    }

    /**
     * 写入单个保持寄存器
     * @param master ModbusMaster对象
     * @param slaveId 从站ID
     * @param offset 寄存器地址
     * @param value 写入的值
     * @return 写入是否成功
     */
    public static boolean writeRegister(ModbusMaster master, int slaveId, int offset, int value) throws ModbusTransportException {
        WriteRegisterRequest request = new WriteRegisterRequest(slaveId, offset, value);
        try {
            master.send(request);
            return true;
        } catch (ModbusTransportException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 关闭Modbus连接
     * @param master ModbusMaster对象
     */
    public static void closeModbusMaster(ModbusMaster master) {
        if (master != null) {
            master.destroy();
        }
    }

    /**
     * 通过modbus读取
     * @param slaverId  从机地址
     */
    public synchronized static String read(Integer slaverId) throws ModbusTransportException, InterruptedException {
        String commPortId = "COM3"; // 串口ID
        int baudRate = 9600; // 波特率

        ModbusMaster master = initModbusSerialMaster2(commPortId, baudRate);
        if (master != null) {
            // 读取操作
            short[] registerValues = readHoldingRegisters(master, slaverId, 10, 2);
            if (registerValues != null) {
                String[] hexData = new String[registerValues.length];
                for (int i = 0; i < registerValues.length; i++) {
                    hexData[i] = String.format("%04X", registerValues[i] & 0xFFFF);
                }
                    int intBits = Integer.parseUnsignedInt(hexData[0]+hexData[1], 16);//将原16进制值转化为整数
                    float floatValue = Float.intBitsToFloat(intBits);//再将整数转化为浮点数
                    DecimalFormat df = new DecimalFormat("#");//浮点数之后支取两位
                    String formattedValue = df.format(floatValue);
                    System.out.println("浮点数: " + formattedValue);
                    closeModbusMaster(master);//关闭连接
                    return formattedValue;

            }
            // 关闭连接
            closeModbusMaster(master);
            return null;
        }else {
            return null;
        }
    }

    public static void main(String[] args) throws ModbusTransportException, InterruptedException {
        String commPortId = "COM3"; // 串口ID
        int baudRate = 9600; // 波特率

        ModbusMaster master = initModbusSerialMaster2(commPortId, baudRate);
        if (master != null) {
            // 读取操作
            short[] registerValues = readHoldingRegisters(master, 4, 10, 2);
            if (registerValues != null) {
                for (short value : registerValues) {
                    System.out.println("Register Value: " + value);
                }
            }

//            // 写入操作
//            boolean writeResult = writeRegister(master, 1, 0, 100);
//            if (writeResult) {
//                System.out.println("写入成功");
//            }

            // 关闭连接
            closeModbusMaster(master);
        }
    }
    /**
     * 初始化Modbus串行连接
     * @param commPortId 串口名称（如COM3）
     * @param baudRate 波特率
     * @return 返回ModbusMaster对象
     */
    public static ModbusMaster initModbusSerialMaster2(String commPortId, int baudRate) {
        // 创建Modbus工厂
        ModbusFactory modbusFactory = new ModbusFactory();
        // 设置串行参数
        SerialPortWrapper serialPortWrapper = new SerialPortWrapperImpl(commPortId,baudRate,8,1,0,0,0);

        // 创建ModbusMaster
        ModbusMaster master = modbusFactory.createRtuMaster(serialPortWrapper);
//        master.setTimeout(2000);  // 设置超时为2000毫秒（2秒）
//        master.setRetries(0);     // 如果需要，可以设置重试次数
        try {
            master.init();
            return master;
        } catch (ModbusInitException e) {
            e.printStackTrace();
            return null;
        }
    }
}
